package OBJ_Loader;

import graphic.Graphic;
import java.util.ArrayList;
import java.util.List;
import klient.Klient;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;

/**
 *  
 * @author Marcin & Bartek
 * 
 * @description Defines primitive Triangles and faces of any Object in the Game 
 * 
 */
public class Model {
    private List<Vector3f> vert= new ArrayList<>();
    private List<Vector3f> norm= new ArrayList<>();
    private List<Vector2f> uv= new ArrayList<>();
    private List<Face> face= new ArrayList<>();
    private List<Texture> tex = new ArrayList<>();
    private MTLObj mtl;
    private int ID;
    public void draw(Vector3f pos,Vector3f rot, float scale, boolean mx, boolean my, boolean mz,boolean reverse,boolean dual){
        Graphic.e.push();
        if(reverse) Graphic.e.reverseCull();
        if(dual) Graphic.e.dualCull();
        Graphic.e.translate(pos);    
        if(rot.x!=0) Graphic.e.rotX(rot.x);
        if(rot.y!=0) Graphic.e.rotY(rot.y);
        if(rot.z!=0) Graphic.e.rotZ(rot.z);
        Graphic.e.scale((mx?-scale:scale),(my?-scale:scale),(mz?-scale:scale));
        Graphic.e.drawList(getID());
        if(reverse || dual) Graphic.e.normalCull();
        Graphic.e.pop();
    }
    
    public Model(){
        ID=Graphic.e.createList();
    }
    
    public void compile(){
        Material actM;
        Texture act=null;
        actM=getFace().get(0).getM();
        if(actM!=null) act=actM.getTex();
        boolean init=true;
        Graphic.e.startList(getID());
        {
            Graphic.e.startDrawT();
            for(Face f : getFace()){
                if(init){
                    init=false;
                    Graphic.e.endDraw();
                    if(act!=null) Graphic.e.bind(actM.getTex());
                    else Graphic.e.unbind();
                    Graphic.e.startDrawT();
                }else{
                    if(actM!=f.getM()){
                        actM=f.getM();
                        if(actM!=null && actM.getTex()!=null){
                            act=actM.getTex();
                            Graphic.e.endDraw();
                            Graphic.e.bind(act);
                            Graphic.e.startDrawT();
                        }else{
                            Graphic.e.endDraw();
                            Graphic.e.unbind();
                            Graphic.e.startDrawT();
                        }
                    }
                }
                
                if(act!=null)Graphic.e.textCoord(getUv().get((int)f.getTexI().x-1));
                Graphic.e.setNormal(getNorm().get((int)f.getNormI().x-1));
                Graphic.e.drawVertex(getVert().get((int)f.getVecI().x-1));
                
                if(act!=null)Graphic.e.textCoord(getUv().get((int)f.getTexI().y-1));
                Graphic.e.setNormal(getNorm().get((int)f.getNormI().y-1));
                Graphic.e.drawVertex(getVert().get((int)f.getVecI().y-1));
                
                if(act!=null)Graphic.e.textCoord(getUv().get((int)f.getTexI().z-1));
                Graphic.e.setNormal(getNorm().get((int)f.getNormI().z-1));
                Graphic.e.drawVertex(getVert().get((int)f.getVecI().z-1));
                
            }            
            Graphic.e.endDraw();
            Graphic.e.unbind();
        }
        Graphic.e.endList();
    }            

    /**
     * @return the vert
     */
    public List<Vector3f> getVert() {
        return vert;
    }

    /**
     * @param vert the vert to set
     */
    public void setVert(List<Vector3f> vert) {
        this.vert = vert;
    }

    /**
     * @return the norm
     */
    public List<Vector3f> getNorm() {
        return norm;
    }

    /**
     * @param norm the norm to set
     */
    public void setNorm(List<Vector3f> norm) {
        this.norm = norm;
    }

    /**
     * @return the uv
     */
    public List<Vector2f> getUv() {
        return uv;
    }

    /**
     * @param uv the uv to set
     */
    public void setUv(List<Vector2f> uv) {
        this.uv = uv;
    }

    /**
     * @return the face
     */
    public List<Face> getFace() {
        return face;
    }

    /**
     * @param face the face to set
     */
    public void setFace(List<Face> face) {
        this.face = face;
    }

    /**
     * @return the tex
     */
    public List<Texture> getTex() {
        return tex;
    }

    /**
     * @param tex the tex to set
     */
    public void setTex(List<Texture> tex) {
        this.tex = tex;
    }

    /**
     * @return the mtl
     */
    public MTLObj getMtl() {
        return mtl;
    }

    /**
     * @param mtl the mtl to set
     */
    public void setMtl(MTLObj mtl) {
        this.mtl = mtl;
    }

    /**
     * @return the ID
     */
    public int getID() {
        return ID;
    }

    /**
     * @param ID the ID to set
     */
    public void setID(int ID) {
        this.ID = ID;
    }
}
